package com.jdrx.ocp.service;

import com.jdrx.ocp.beans.constans.EDeleteFlag;
import com.jdrx.ocp.beans.constans.EDeptType;
import com.jdrx.ocp.beans.constans.EventActionEnum;
import com.jdrx.ocp.beans.constans.EventEnum;
import com.jdrx.ocp.beans.dto.dept.CreateDeptDTO;
import com.jdrx.ocp.beans.dto.dept.QueryByIdsDTO;
import com.jdrx.ocp.beans.dto.dept.QueryDeptDTO;
import com.jdrx.ocp.beans.dto.dept.UpdateDeptDTO;
import com.jdrx.ocp.beans.dto.system.FindDeptLeaderByUserIdsDTO;
import com.jdrx.ocp.beans.entity.DeptPO;
import com.jdrx.ocp.beans.entity.UserPO;
import com.jdrx.ocp.beans.entity.util.ExceptionMessageFilter;
import com.jdrx.ocp.beans.event.NoticesEvent;
import com.jdrx.ocp.beans.vo.QueryDeptAndUserManagerVO;
import com.jdrx.ocp.beans.vo.QueryDeptTreeVO;
import com.jdrx.ocp.beans.vo.QueryDeptVO;
import com.jdrx.ocp.dao.DeptDAO;
import com.jdrx.ocp.dao.UserDAO;
import com.jdrx.platform.commons.rest.beans.dto.IdDTO;
import com.jdrx.platform.commons.rest.exception.BizException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 部门处理
 *
 * @Author: Huangxg
 * @Date: 2018/11/19 11:24
 */
@Service
public class DeptService {

    private static final Logger logger = LoggerFactory.getLogger(DeptService.class);
    @Autowired
    DeptDAO deptDAO;

    @Autowired
    NoticeEventService noticeEventService;

    @Autowired
    UserDAO userDAO;

    @Autowired
    AdminService adminService;

    /**
     * 查询参数处理
     *
     * @param queryDeptDTO
     * @return
     */
    private Map<String, Object> initQueryMap(QueryDeptDTO queryDeptDTO) {
        Map<String, Object> map = new HashMap<String, Object>(5);
        map.put("delFlag", EDeleteFlag.NORMAL.getKey());
        map.put("name", queryDeptDTO.getName());
        map.put("pId", queryDeptDTO.getpId());
        return map;
    }

    /**
     * 根据ID查找部门
     *
     * @param id
     * @return
     */
    public QueryDeptVO queryOne(Long id) throws BizException {
        try {
            DeptPO deptPO = deptDAO.getById(id);
            if (deptPO == null) {
                return null;
            }
            QueryDeptVO queryDeptVO = new QueryDeptVO();
            BeanUtils.copyProperties(deptPO, queryDeptVO);
            return queryDeptVO;
        } catch (Exception e) {
            throw new BizException("查询部门失败！");
        }
    }

    /**
     * 根据ID集查找部门
     *
     * @param queryByIdsDTO
     * @return
     */
    public List<QueryDeptVO> queryByIds(QueryByIdsDTO queryByIdsDTO) {
        List<DeptPO> list = deptDAO.queryByIds(queryByIdsDTO.getIds());
        List<QueryDeptVO> reList = new ArrayList<>();
        list.forEach(item -> {
            QueryDeptVO queryDeptVO = new QueryDeptVO();
            BeanUtils.copyProperties(item, queryDeptVO);
            reList.add(queryDeptVO);
        });
        return reList;
    }

    /**
     * 部门信息查询
     *
     * @param queryDeptDTO
     * @return
     * @throws BizException
     */
    public List<QueryDeptVO> queryDept(QueryDeptDTO queryDeptDTO) throws BizException {
        try {
            Map<String, Object> queryMap = initQueryMap(queryDeptDTO);
            return generateQueryDeptVO(deptDAO.listBy(queryMap));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("查询部门失败！");
        }
    }

    /**
     * 获取机构部门树（所有）
     *
     * @return
     * @throws BizException
     */
    public List<QueryDeptTreeVO> getDeptForTree() throws BizException {
        try {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("delFlag", EDeleteFlag.NORMAL.getKey());
            List<DeptPO> list = deptDAO.listBy(queryMap);
            logger.debug("list count = " + list.size());
            return getDeptTree(list, 0);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取部门树信息失败！");
        }
    }

    /**
     * 获取某个公司下的部门树
     *
     * @return
     * @throws BizException
     */
    public List<QueryDeptTreeVO> getOrgForTree(Integer companyId) throws BizException {
        try {
            List<Long> childs = getChildIds(Long.valueOf(companyId));
            if (childs != null && childs.size() > 0) {
                childs.remove(companyId);
            }
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("delFlag", EDeleteFlag.NORMAL.getKey());
//            queryMap.put("type",EDeptType.DEPT.getKey());
            queryMap.put("ids", childs);
            List<DeptPO> list = deptDAO.listBy(queryMap);
            return getDeptTree(list, companyId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 获取公司树（仅只有公司数据）
     *
     * @return
     * @throws BizException
     */
    public List<QueryDeptTreeVO> getCompanyForTree(Long deptId) throws BizException {
        try {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("delFlag", EDeleteFlag.NORMAL.getKey());
            queryMap.put("type", EDeptType.COMPANY.getKey());
            if (deptId != null && deptId > 0) {
                queryMap.put("ids", this.getChildIds(deptId));
            }
            List<DeptPO> list = deptDAO.listBy(queryMap);
            return getDeptTree(list, 0);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 查询返回结构体
     *
     * @param datas
     * @return
     * @throws BizException
     */
    private List<QueryDeptVO> generateQueryDeptVO(List<DeptPO> datas) throws BizException {
        try {
            List<QueryDeptVO> list = new ArrayList<QueryDeptVO>();
            if (null == datas || CollectionUtils.isEmpty(datas)) {
                return list;
            }
            QueryDeptVO vo = null;
            for (DeptPO row : datas) {
                vo = new QueryDeptVO();
                BeanUtils.copyProperties(row, vo);
                if (row.getPid() > 0) {
                    for (DeptPO r : datas) {
                        if (r.getId() == row.getPid().longValue()) {
                            vo.setpName(r.getName());
                            break;
                        }
                    }
                }
                vo.setpName(Optional.ofNullable(vo.getpName()).orElse(""));
                list.add(vo);
            }
            return list;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 添加部门信息
     *
     * @param createDeptDTO
     * @return
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public int createDept(CreateDeptDTO createDeptDTO, Integer uId , String tid) throws BizException {
        //是否已存在该部门
        Map<String, Object> queryMap = new HashMap<String, Object>(3);
        queryMap.put("eqName", createDeptDTO.getName());
        queryMap.put("pId", createDeptDTO.getPid());
        queryMap.put("delFlag", EDeleteFlag.NORMAL.getKey());
        List<DeptPO> list = deptDAO.listBy(queryMap);
        if (!CollectionUtils.isEmpty(list) && list.size() > 0) {
            throw new BizException("该部门已存在");
        }
        //不存在则添加部门
        DeptPO deptPO = new DeptPO();
        BeanUtils.copyProperties(createDeptDTO, deptPO);
        Date nowTime = new Date();
        deptPO.setCreateAt(nowTime);
        deptPO.setCreateBy(uId.intValue());
        deptPO.setDelFlag(EDeleteFlag.NORMAL.getKey().toString());
        deptPO.setUpdateAt(nowTime);
        deptPO.setUpdateBy(uId.intValue());
        deptPO.setType(createDeptDTO.getType());
        int num = deptDAO.insert(deptPO);
        if (num > 0) {
            //更新缓存
            adminService.addRedisDept(deptPO , tid);
            noticeEventService.publishEvent(new NoticesEvent(this, EventEnum.DEPT, EventActionEnum.CREATE));
        }
        return num;
    }

    /**
     * 更新部门信息
     *
     * @param updateDeptDTO
     * @return
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateDept(UpdateDeptDTO updateDeptDTO, Integer uId , String tid) throws BizException {
        DeptPO old = deptDAO.getById(updateDeptDTO.getId());
        if (null == old) {
            throw new BizException("更新对象不存在");
        }
        List<Long> childIds = this.getChildIds(updateDeptDTO.getId());
        if(childIds != null && childIds.size() > 0){
            if(childIds.contains(Long.valueOf(updateDeptDTO.getPid()))){
                throw new BizException("上级部门不能设置为当前部门或子部门");
            }
        }
        if (updateDeptDTO.getName() != null) {
            Map<String, Object> existMap = new HashMap<>();
            existMap.put("name", updateDeptDTO.getName());
            existMap.put("id", updateDeptDTO.getId());
            existMap.put("pid", updateDeptDTO.getPid());
            DeptPO existDept = deptDAO.deptExist(existMap);
            if (existDept != null) {
                throw new BizException("该部门已存在");
            }
        }
        DeptPO newDept = new DeptPO();
        BeanUtils.copyProperties(updateDeptDTO, newDept);
        Date nowTime = new Date();
        newDept.setUpdateBy(uId);
        newDept.setUpdateAt(nowTime);
        int num = deptDAO.update(newDept);
        if (num > 0) {
            //更新缓存
            adminService.addRedisDept(newDept , tid);
            noticeEventService.publishEvent(new NoticesEvent(this, EventEnum.DEPT, EventActionEnum.MODIDY));
        }
        return num;
    }

    /**
     * 删除部门,逻辑删除
     *
     * @param id
     * @return
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDept(IdDTO id, Integer uId) throws BizException {
        try {
            Long deptId = Long.valueOf(id.getId().toString());
            //部门及其子级部门下是否存在用户
            if (existUser(deptId)) {
                String error = "该部门或子级部门下存在用户";
                logger.info(error);
                throw new BizException(error);
            }
            Boolean bol = deleteDeptAndChild(deptId);
            if (bol) {
                noticeEventService.publishEvent(new NoticesEvent(this, EventEnum.DEPT, EventActionEnum.DELETE));
            }
            return bol;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * List转map树
     *
     * @param list
     * @param pid
     * @return
     */
    private List<Map<String, Object>> getDeptTreeForMap(List<DeptPO> list, Object pid) {
        List<Map<String, Object>> itemList = new ArrayList<>();
        for (DeptPO item : list) {
            if (pid.toString().equals(item.getPid().toString())) {
                Map<String, Object> queryDeptTreeVO = com.jdrx.platform.commons.rest.utils.BeanUtils.populate(item);
                List<Map<String, Object>> obj = getDeptTreeForMap(list, item.getId());
                if (obj != null && obj.size() > 0) {
                    queryDeptTreeVO.put("children", obj);
                }
                queryDeptTreeVO.remove("createAt");
                queryDeptTreeVO.remove("createBy");
                queryDeptTreeVO.remove("updateBy");
                queryDeptTreeVO.remove("updateAt");
                itemList.add(queryDeptTreeVO);
            }
        }
        return itemList;
    }

    /**
     * List转树
     *
     * @param list
     * @param pid
     * @return
     */
    private List<QueryDeptTreeVO> getDeptTree(List<DeptPO> list, Object pid) {
        List<QueryDeptTreeVO> itemList = new ArrayList<>();
        QueryDeptTreeVO queryDeptTreeVO = null;
        for (DeptPO item : list) {
            if (pid.toString().equals(item.getPid().toString())) {
                queryDeptTreeVO = new QueryDeptTreeVO();
                BeanUtils.copyProperties(item, queryDeptTreeVO);
                List<QueryDeptTreeVO> obj = getDeptTree(list, item.getId());
                queryDeptTreeVO.setChildren(obj);
                itemList.add(queryDeptTreeVO);
            }
        }
        return itemList;
    }

    /**
     * 获取指定节点的所有子节点包含其本身
     *
     * @param list
     * @param pid
     * @return
     */
    private Set<Long> getDeptChildrenIds(List<DeptPO> list, Long pid) {
        Set<Long> itemList = new HashSet<>();
        itemList.add(pid);
        for (DeptPO item : list) {
            if (pid.toString().equals(item.getPid().toString())) {
                itemList.add(Long.valueOf(item.getPid()));
                itemList.addAll(getDeptChildrenIds(list, Long.valueOf(item.getId())));
            }
        }
        return itemList;
    }

    /**
     * 获取部门子级，包含其本身
     *
     * @param id
     * @return
     * @throws BizException
     */
    public List<Long> getChildIds(Long id) throws BizException {
        try {
            Map<String, Object> map = new HashMap<>(3);
            map.put("delFlag", EDeleteFlag.NORMAL.getKey());
            return new ArrayList<>(this.getDeptChildrenIds(deptDAO.listBy(map), id));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取子级id失败！");
        }
    }

//    /**
//     * 获取部门子级，包含其本身
//     * @param id
//     * @return
//     * @throws BizException
//     */
//    public List<Long> getChildIds(Long id) throws BizException {
//        try{
//            return deptDAO.queryDeptChildIds(id);
//        }catch (Exception e){
//            logger.error(e.getMessage(),e);
//            throw new BizException("获取数据失败！");
//        }
//    }

    /**
     * 部门下是否存在用户，包含子级部门用户
     *
     * @param id
     * @return
     * @throws BizException
     */
    private boolean existUser(Long id) throws BizException {
        try {
            //子级部门
            List<Long> ids = getChildIds(id);
            if (CollectionUtils.isEmpty(ids) || ids.size() == 0) {
                throw new BizException("不存在的部门");
            }
            if (deptDAO.queryDeptIdsUserCount(ids) > 0) {
                return true;
            }
            return false;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * 删除部门及其子级部门 - 逻辑删除
     *
     * @param id
     * @return
     * @throws BizException
     */
    private boolean deleteDeptAndChild(Long id) throws BizException {
        try {
            //获取本身及其子级部门ID集
            List<Long> ids = getChildIds(id);
            //如果没有数据则直接返回false
            if (CollectionUtils.isEmpty(ids) || ids.size() == 0) {
                throw new BizException("不存在需要删除的数据");
            }
            //执行删除操作
            if (deptDAO.deleteDeptAndChild(ids) >= 0) {
                return true;
            }
            throw new BizException("执行删除操作失败");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * 获取子级及本身的部门信息
     *
     * @param id
     * @return
     * @throws BizException
     */
    public List<QueryDeptVO> getDeptChildren(Long id) throws BizException {
        try {
            List<DeptPO> list;
            if (id == 0) {
                Map<String, Object> map = new HashMap<>(3);
                map.put("delFlag", EDeleteFlag.NORMAL.getKey());
                list = deptDAO.listBy(map);
            } else {
                List<Long> ids = getChildIds(id);
                if (CollectionUtils.isEmpty(ids)) {
                    return Collections.emptyList();
                }
                list = deptDAO.queryByIds(ids);
            }
            List<QueryDeptVO> reList = new ArrayList<>();
            list.forEach(row -> {
                QueryDeptVO queryDeptVO = new QueryDeptVO();
                BeanUtils.copyProperties(row, queryDeptVO);
                reList.add(queryDeptVO);
            });
            return reList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 获取子级及本身的部门信息
     *
     * @param id
     * @return
     * @throws BizException
     */
    public List<Map<String, Object>> getDeptChildrenToTree(Long id) throws BizException {
        List<QueryDeptVO> list = this.getDeptChildren(id);
        List<DeptPO> poList = new ArrayList<>();
        Integer pid = id.intValue();

        for (QueryDeptVO item : list) {
            if (item.getId().equals(id)) {
                pid = item.getPid();
            }
            DeptPO vo = new DeptPO();
            BeanUtils.copyProperties(item, vo);
            poList.add(vo);
        }
        return this.getDeptTreeForMap(poList, pid);
    }

    /**
     * 获取指定部门的父级部门
     *
     * @param list
     * @param deptId
     * @param reList
     */
    public void getDeptParents(List<QueryDeptVO> list, Long deptId, List<QueryDeptVO> reList) {
        for (QueryDeptVO row : list) {
            if (row.getId().equals(deptId)) {
                reList.add(row);
                getDeptParents(list, Long.valueOf(row.getPid()), reList);
                break;
            }
        }
    }

    /**
     * 根据用户ids获取部门负责人
     *
     * @param findDeptLeaderByUserIdsDTO
     * @return
     */
    public List<UserPO> findDeptLeaderByUserIds(FindDeptLeaderByUserIdsDTO findDeptLeaderByUserIdsDTO) throws BizException {
        return userDAO.findDeptLeaderByUserIds(findDeptLeaderByUserIdsDTO.getIds());
    }

    /**
     * 获取指定部门的父级部门
     *
     * @param deptId
     * @return
     * @throws BizException
     */
    public List<QueryDeptVO> getDeptParents(Long deptId) throws BizException {
        try {
            List<QueryDeptVO> list = queryDept(new QueryDeptDTO());
            List<QueryDeptVO> reList = new ArrayList<>();
            getDeptParents(list, deptId, reList);
            return reList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 将列表转为map
     *
     * @param list
     * @return
     */
    private Map<Long, QueryDeptVO> formatDeptForMap(List<QueryDeptVO> list) {
        if (list != null && list.size() > 0) {
            Map<Long, QueryDeptVO> map = new HashMap<>(list.size());
            list.forEach(item -> {
                map.put(item.getId(), item);
            });
            return map;
        }
        return new HashMap<>();
    }

    /**
     * 获取指定ID集的所有父节点
     *
     * @param ids
     * @return
     */
    public List<Long> getDeptAllParents(List<Long> ids) throws BizException {
        try {
            List<QueryDeptVO> allList = queryDept(new QueryDeptDTO());
            Map<Long, QueryDeptVO> allMap = formatDeptForMap(allList);
            List<Long> reList = new ArrayList<>();
            if (ids != null && ids.size() > 0) {
                for (Long id : ids) {
                    if (allMap.containsKey(id)) {
                        RecParents(id, allMap, reList);
                    }
                }
            }
            return reList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 获取指定ID的父ID
     *
     * @param id
     * @param map
     * @param reList
     */
    private void RecParents(Long id, Map<Long, QueryDeptVO> map, List<Long> reList) {
        if (id > 0 && !reList.contains(id)) {
            reList.add(id);
            QueryDeptVO pVo = map.get(id);
            if (pVo != null && pVo.getPid() > 0) {
                RecParents(Long.valueOf(pVo.getPid()), map, reList);
            }
        }
    }

    /**
     * 根据部门名称查询部门负责人
     *
     * @param deptName
     * @return
     */
    public Map<String, Object> queryDeptUserManager(String deptName) throws BizException {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("name", deptName);
            List<DeptPO> deptPOs = deptDAO.queryDeptByName(map);
            if (CollectionUtils.isEmpty(deptPOs)) {
                throw new BizException("该部门不存在");
            }

            Map<String, Object> userMap = new HashMap<>();
            userMap.put("deptId", deptPOs.get(0).getId());
            userMap.put("isAdmin", 1);
            List<UserPO> userPOs = userDAO.listBy(userMap);
            if (CollectionUtils.isEmpty(userPOs)) {
                throw new BizException("该单位不存在负责人");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("dept", deptPOs.get(0));
            result.put("user", userPOs.get(0));
            return result;
        } catch (Exception e) {
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * 查询部门及部门负责人列表
     *
     * @return
     */
    public List<QueryDeptAndUserManagerVO> queryDeptAndUserManagerList() throws BizException {
        try {
            List<QueryDeptAndUserManagerVO> datas = new ArrayList<>();
            List<DeptPO> deptPOs = deptDAO.listBy(new HashMap<>());
            if (CollectionUtils.isEmpty(deptPOs)) {
                throw new BizException("当前还没有配置组织机构");
            }

            Map<String, Object> userMap = new HashMap<>();
            //鹿泉营收系统、报装系统均使用了该字段，导致报装系统该条件设置冲突，故取消该条件
            //userMap.put("isAdmin", 1);
            List<UserPO> userPOs = userDAO.listBy(userMap);
            if (CollectionUtils.isEmpty(userPOs)) {
                throw new BizException("当前不存在部门负责人");
            }

            /*for(DeptPO d : deptPOs){
                QueryDeptAndUserManagerVO vo = new QueryDeptAndUserManagerVO();
                vo.setId(d.getId());
                vo.setPid(d.getPid());
                vo.setName(d.getName());
                for(UserPO u : userPOs){
                    if(u.getDeptId().equals(d.getId())){
                        vo.setUserId(u.getId());
                        vo.setUserName(u.getRealName());
                        break;
                    }
                }
                datas.add(vo);
            }*/

            // 一个部门具有多个负责人，外层循环改为负责人列表
            for (UserPO u : userPOs) {
                QueryDeptAndUserManagerVO vo = new QueryDeptAndUserManagerVO();
                vo.setUserId(u.getId());
                vo.setUserName(u.getRealName());

                for (DeptPO d : deptPOs) {
                    if (u.getDeptId().equals(d.getId())) {
                        vo.setId(d.getId());
                        vo.setPid(d.getPid());
                        vo.setName(d.getName());

                        datas.add(vo);
                        break;
                    }
                }
            }

            // 按上级部门id排序
            datas = datas.stream().sorted(Comparator.comparing(QueryDeptAndUserManagerVO::getId)).collect(Collectors.toList());
            return datas;
        } catch (Exception e) {
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * 将机构信息存入缓存
     */
    public void storageRedisDept() {
//        adminService.storageRedisDept(deptDAO.listBy(null));
        this.storageRedisDept("");
    }

    /**
     * 将机构信息存入缓存
     */
    public void storageRedisDept(String tid) {
        adminService.storageRedisDept(deptDAO.listBy(null), tid);
    }

    /**
     * 根据机构id获取最顶层的机构
     *
     * @param id
     * @return
     */
    public DeptPO getTopDept(Long id) {

        DeptPO deptPO = deptDAO.getById(id);
        if(deptPO == null){
            return null;
        }
        if (deptPO.getType().equals(EDeptType.COMPANY.getKey())) {
            return deptPO;
        }
        return getTopDept(Long.valueOf(deptPO.getPid()));
    }

    /**
     * 获取顶层机构信息
     *
     * @return
     */
    public DeptPO getTopDept() {
        return deptDAO.getTopDept();
    }

    /**
     * 创建或更新顶级机构名称，用于saas平台创建用户时的初始化机构信息添加或更新
     * 如果有默认初始值则直接更新名称，否则是创建一个顶层机构信息
     *
     * @param name
     * @param uid
     * @throws BizException
     */
    public DeptPO createOrUpdateTopDept(String name, Integer uid , String tid) throws BizException {
        boolean bol = false;
        DeptPO po = this.getTopDept();
        if (po != null) {
            po.setName(name);
            po.setUpdateAt(new Date());
            deptDAO.update(po);
        } else {
            CreateDeptDTO deptDTO = new CreateDeptDTO();
            deptDTO.setName(name);
            deptDTO.setPid(0);
            deptDTO.setType(1);
            this.createDept(deptDTO, uid , tid);
        }
        return this.getTopDept();
    }

    /**
     * 获取当前登录用户的所有部门列表
     *
     * @param id
     * @return
     * @throws BizException
     */
    public List<QueryDeptVO> queryCurrentDepts(Long id) throws BizException {
        try {
            List<QueryDeptVO> reList = getDeptChildren(id);
            return reList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 根据部门名称查询部门用户列表（含子部门用户）
     *
     * @param deptName
     * @return
     */
    public List<UserPO> queryDeptUserByDeptName(String deptName) throws BizException {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("name", deptName);
            List<DeptPO> deptPOs = deptDAO.queryDeptByName(map);
            if (CollectionUtils.isEmpty(deptPOs)) {
                throw new BizException("该部门不存在");
            }
            List<Long> deptIds = getChildIds(deptPOs.get(0).getId());
            if (CollectionUtils.isEmpty(deptIds)) {
                return new ArrayList<>();
            }
            Map<String, Object> userMap = new HashMap<>();
            userMap.put("deptIds", deptIds);
            List<UserPO> userPOs = userDAO.listBy(userMap);
            return userPOs;
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 根据部门名称查询部门负责人列表
     *
     * @param deptName
     * @return
     */
    public Map<String, Object> queryDeptUserManagerList(String deptName) throws BizException {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("name", deptName);
            List<DeptPO> deptPOs = deptDAO.queryDeptByName(map);
            if (CollectionUtils.isEmpty(deptPOs)) {
                throw new BizException("该部门不存在");
            }

            Map<String, Object> userMap = new HashMap<>();
            userMap.put("deptId", deptPOs.get(0).getId());
            userMap.put("isAdmin", 1);
            List<UserPO> userPOs = userDAO.listBy(userMap);
            if (CollectionUtils.isEmpty(userPOs)) {
                throw new BizException("该单位不存在负责人");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("dept", deptPOs.get(0));
            result.put("userList", userPOs);
            return result;
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 获取部门的父级路径
     *
     * @param deptId
     * @return
     * @throws BizException
     */
    public String getDeptParentsPath(Long deptId) throws BizException {
        return deptParentsPath(deptId);
//        List<QueryDeptVO> list = this.getDeptParents(deptId);
//        List<Long> path = new ArrayList<>();
//        if (list != null) {
//            list.forEach(vo -> {
//                path.add(vo.getId());
//            });
//            Object[] args = path.toArray();
//            Arrays.sort(args);
//            return StringUtils.arrayToDelimitedString(args, "/");
//        }
//        return "";
    }

    public String deptParentsPath(Long deptId) throws BizException {
        List<QueryDeptVO> list = this.getDeptParents(deptId);
        String path = deptPath(list,0);
        if(!StringUtils.isEmpty(path)){
            path = path.substring(1);
        }
        return path;
    }

    private String deptPath(List<QueryDeptVO> list , Integer pid ){
        StringBuilder path = new StringBuilder();
        if(!CollectionUtils.isEmpty(list)){
            for(QueryDeptVO vo : list){
                if(pid.equals(vo.getPid())){
                    path.append("/").append(vo.getId());
                    String nextPath = deptPath(list,vo.getId().intValue());
                    if(!StringUtils.isEmpty(nextPath)){
                        path.append(nextPath);
                    }
                }
            }
        }
        return path.toString();
    }

}
